package com.couldsail.takeaway.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.couldsail.takeaway.common.result.PageResult;
import com.couldsail.takeaway.constant.BusinessNameConstant;
import com.couldsail.takeaway.constant.CouponConstant;
import com.couldsail.takeaway.constant.MessageConstant;
import com.couldsail.takeaway.constant.OrdersConstant;
import com.couldsail.takeaway.context.BaseContext;
import com.couldsail.takeaway.execption.AddressBookBusinessException;
import com.couldsail.takeaway.execption.ShoppingCartBusinessException;
import com.couldsail.takeaway.mapper.*;
import com.couldsail.takeaway.pojo.dto.OrderCancelDTO;
import com.couldsail.takeaway.pojo.dto.OrdersDTO;
import com.couldsail.takeaway.pojo.dto.ShoppingCartDTO;
import com.couldsail.takeaway.pojo.entity.*;
import com.couldsail.takeaway.pojo.vo.OrderVO;
import com.couldsail.takeaway.pojo.vo.ShopVO;
import com.couldsail.takeaway.service.OrdersService;
import com.couldsail.takeaway.service.ShoppingCartService;
import com.couldsail.takeaway.utils.UniqueIdGenerator;
import com.sun.xml.bind.v2.TODO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;


@Service
@RequiredArgsConstructor
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {

    private final OrdersMapper orderMapper;
    private final OrderDetailMapper orderDetailMapper;
    private final ShoppingCartMapper shoppingCartMapper;
    private final AddressBookMapper addressBookMapper;
    private final ShopMapper shopMapper;
    private final ProductsMapper productsMapper;
    private final ShoppingCartService shoppingCartService;
    private final UserCouponMapper userCouponMapper;
    private final CouponMapper couponMapper;

    /**
     * 用户下单
     *
     * @param ordersDTO
     */
    @Transactional
    public void submitOrder(OrdersDTO ordersDTO) {
        String uuid = UniqueIdGenerator.generateUniqueId();
        // 获取当前用户id
        String userId = BaseContext.getCurrentId();
        // 查看用户的购物车是否为空
        LambdaQueryWrapper<ShoppingCart> shoppingCartWrapper = new LambdaQueryWrapper<>();
        shoppingCartWrapper.eq(ShoppingCart::getShopId, ordersDTO.getShopId()).eq(ShoppingCart::getUserId, userId);
        List<ShoppingCart> shoppingCartList = shoppingCartMapper.selectList(shoppingCartWrapper);
        if (shoppingCartList == null) {
            // 抛出异常接触进程
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }
        // 获取相关店铺的设置
        Shop shop = shopMapper.selectById(ordersDTO.getShopId());
        // 判读店铺当前状态
        if (!Objects.equals(shop.getBusinessStatus(), BusinessNameConstant.business_status_rest)) {
            throw new ShoppingCartBusinessException(MessageConstant.SHOP_NOT_PAY);
        }
        if (Objects.equals(shop.getStatus(), BusinessNameConstant.shop_status_forbid)) {
            throw new ShoppingCartBusinessException(MessageConstant.SHOP_LOCKED);
        }
        if (Objects.equals(shop.getStatus(), BusinessNameConstant.shop_status_under_review)) {
            throw new ShoppingCartBusinessException(MessageConstant.SHOP_UNDER_REVIEW);
        }
        // 构建订单对象
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersDTO, orders);
        orders.setUserId(userId);
        orders.setId(UniqueIdGenerator.generateUniqueId());
        orders.setNumber(uuid);
        orders.setShopId(ordersDTO.getShopId());
        orders.setOrderTime(LocalDateTime.now());
        orders.setStatus(OrdersConstant.ORDER_STATUS_WAIT_PAY); // 待付款
        orders.setPayStatus(OrdersConstant.PAY_STATUS_UNPAID); // 未支付
        // 判断订单是否为外卖
        if (Objects.equals(ordersDTO.getSeatStatus(), OrdersConstant.ORDER_STATUS_SUB)) {
            // 检查是否到达起送价
            double total = shoppingCartList.stream()
                    .mapToDouble(item -> item.getAmount() * item.getNumber())
                    .sum();
            if (total < shop.getMinDeliveryPrice()) {
                throw new ShoppingCartBusinessException(MessageConstant.ORDER_NOT_MINDELIVERYPRICE);
            }
            // 查看用户的地址簿是否合规
            AddressBook address = addressBookMapper.selectById(ordersDTO.getAddressBookId());
            if (address != null) {
                // 构建收货人详细
                orders.setAddress(address.getProvinceName() + address.getCityName() + address.getDistrictName());// 构建详细地址
                orders.setPhone(address.getPhone());
                orders.setConsignee(address.getConsignee());
            } else {
                throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
            }
        }
        Double total = 0.00;
        // 餐位费
        if (shop.getSeatFee() > 0 && Objects.equals(ordersDTO.getSeatStatus(), OrdersConstant.ORDER_STATUS_CURRENT)) {
            total += shop.getSeatFee() * ordersDTO.getTablewareNumber();
            orderDetailMapper.insert(OrderDetail.builder()
                    .id(UniqueIdGenerator.generateUniqueId())
                    .orderId(orders.getId())
                    .number(ordersDTO.getTablewareNumber())
                    .type(BusinessNameConstant.order_detail_other)
                    .amount(shop.getSeatFee())
                    .name(BusinessNameConstant.seatFee)
                    .build());
        }
        // 餐具费
        if (shop.getTablewareFee() > 0 && Objects.equals(ordersDTO.getSeatStatus(), OrdersConstant.ORDER_STATUS_CURRENT)) {
            total += shop.getTablewareFee() * ordersDTO.getTablewareNumber();
            orderDetailMapper.insert(OrderDetail.builder()
                    .id(UniqueIdGenerator.generateUniqueId())
                    .orderId(orders.getId())
                    .number(ordersDTO.getTablewareNumber())
                    .type(BusinessNameConstant.order_detail_other)
                    .amount(shop.getTablewareFee())
                    .name(BusinessNameConstant.tablewareFee)
                    .build());
        }
        // 打包费
        if (shop.getPackingFee() > 0 && Objects.equals(ordersDTO.getSeatStatus(), OrdersConstant.ORDER_STATUS_SUB)) {
            total += shop.getPackingFee() * BusinessNameConstant.delivery;
            orderDetailMapper.insert(OrderDetail.builder().orderId(orders.getId())
                    .id(UniqueIdGenerator.generateUniqueId())
                    .number(BusinessNameConstant.delivery)
                    .amount(shop.getPackingFee())
                    .type(BusinessNameConstant.order_detail_other)
                    .name(BusinessNameConstant.packingFee)
                    .build());
        }
        // 配送费
        if (shop.getDeliveryFee() > 0 && Objects.equals(ordersDTO.getSeatStatus(), OrdersConstant.ORDER_STATUS_SUB)) {
            total += shop.getDeliveryFee() * BusinessNameConstant.delivery;
            // TODO 配送费是固定值
            orderDetailMapper.insert(OrderDetail.builder().orderId(orders.getId())
                    .id(UniqueIdGenerator.generateUniqueId())
                    .number(BusinessNameConstant.delivery)
                    .amount(shop.getDeliveryFee())
                    .type(BusinessNameConstant.order_detail_other)
                    .name(BusinessNameConstant.deliveryFee)
                    .build());
        }
        BigDecimal totalAmount = shoppingCartList.stream()
                .map(item -> BigDecimal.valueOf(item.getAmount() * item.getNumber()))
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        if (ordersDTO.getVouchers() != null) {
            UserCoupon userCoupon = userCouponMapper.selectById(ordersDTO.getVouchers());

            Coupon coupon = couponMapper.selectById(userCoupon.getCouponId());
            if (coupon == null||Objects.equals(userCoupon.getStatus(),CouponConstant.COUPON_STATUS_USED)) {
                throw new RuntimeException(CouponConstant.NOT_COUPON);
            }

            // 检查优惠券是否在有效期内
            LocalDateTime now = LocalDateTime.now();
            if (now.isBefore(coupon.getValidStart()) || now.isAfter(coupon.getValidEnd())) {
                throw new RuntimeException(CouponConstant.COUPON_NOT_TIME);
            }
            if (Objects.equals(coupon.getType(),CouponConstant.COUPON_TYPE_DISCOUNT)){
                totalAmount = totalAmount.multiply(coupon.getValue());
            }else{
                totalAmount = totalAmount.subtract(coupon.getValue());
            }
            orders.setVouchers(ordersDTO.getVouchers());
            //////
            userCouponMapper.updateById(UserCoupon.builder()
                            .id(userCoupon.getId())
                            .status(CouponConstant.COUPON_STATUS_USED)
                            .usedTime(LocalDateTime.now())
                    .build());
        }
        orders.setAmount(totalAmount.add(BigDecimal.valueOf(total)).setScale(2, RoundingMode.HALF_UP));
        // 保存订单
        orderMapper.insert(orders);
        // 保存订单明细
        shoppingCartList.forEach(detail -> {
            orderDetailMapper.insert(
                    OrderDetail.builder()
                            .id(UniqueIdGenerator.generateUniqueId())
                            .orderId(orders.getId())
                            .name(detail.getName())
                            .amount(detail.getAmount())
                            .image(detail.getImageUrl())
                            .productId(detail.getProductId())
                            .productSpecs(detail.getProductSpecs())
                            .number(detail.getNumber()).build()
            );
        });


        // 清空购物车
        LambdaQueryWrapper<ShoppingCart> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ShoppingCart::getUserId, userId);
        shoppingCartMapper.delete(wrapper);
    }

    /**
     * 查询订单列表
     *
     * @param status
     */
    @Transactional
    public PageResult<OrderVO> getOrderList(String status, long current, Integer size) {
        // 获取当前用户id
        String userId = BaseContext.getCurrentId();

        // 当size为null时，默认设置为10
        if (size == null || size <= 0) {
            size = 10;
        }

        // 创建分页对象
        Page<Orders> page = new Page<>(current, size);

        // 构建查询条件
        LambdaQueryWrapper<Orders> wrapper = buildOrderWrapper(userId, status);

        // 执行分页查询
        Page<Orders> orderPage = orderMapper.selectPage(page, wrapper);

        // 获取订单列表并转换为OrderVO列表
        List<OrderVO> orderVOList = convertToOrderVOList(orderPage.getRecords());
        // 封装分页结果
        return new PageResult<>(orderVOList, orderPage.getCurrent(), orderPage.getPages(), orderPage.getTotal(), orderVOList.size());
    }

    private LambdaQueryWrapper<Orders> buildOrderWrapper(String userId, String status) {
        LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Orders::getUserId, userId)
                .orderByDesc(Orders::getOrderTime);

        // 只有在status不为null时添加状态筛选条件
        if (status != null && !status.trim().isEmpty()) {
            String[] statusArray = status.split(",\\s*");
            wrapper.in(Orders::getStatus, (Object[]) statusArray);
        }
        return wrapper;
    }

    private List<OrderVO> convertToOrderVOList(List<Orders> orders) {
        return orders.stream().map(this::convertToOrderVO).collect(Collectors.toList());
    }

    private OrderVO convertToOrderVO(Orders order) {
        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(order, orderVO);
        // 设置店铺信息
        Shop shop = shopMapper.selectById(order.getShopId());
        ShopVO shopVO = new ShopVO();
        BeanUtils.copyProperties(shop, shopVO);
        orderVO.setShopDetail(shopVO);

        // 查询订单明细
        List<OrderDetail> orderDetails = queryOrderDetails(order.getId());
        double totalAmount = 0.0;
        int totalCount = 0;
        for (OrderDetail item : orderDetails) {
            if (Objects.equals(item.getType(), BusinessNameConstant.order_detail_product)) {
                totalCount++;
                totalAmount += item.getAmount() * item.getNumber();
            }
        }
        orderVO.setTotalAmount(totalAmount);
        orderVO.setTotalNumber(totalCount);
        orderVO.setOrderDetails(orderDetails);
        orderVO.setStatus(order.getStatus());

        return orderVO;
    }

    private List<OrderDetail> queryOrderDetails(String orderId) {
        LambdaQueryWrapper<OrderDetail> detailWrapper = new LambdaQueryWrapper<>();
        detailWrapper.eq(OrderDetail::getOrderId, orderId).eq(OrderDetail::getType, OrdersConstant.ORDER_DETAIL_TYPE_PRODUCT);
        return orderDetailMapper.selectList(detailWrapper);
    }


    /**
     * 取消订单
     *
     * @param orderCancelDTO
     */
    @Override
    public void cancelOrder(OrderCancelDTO orderCancelDTO) {
        // TODO 对应金额退款,退款后修改订单状态OrdersConstant.ORDER_STATUS_CANCELLED

        LambdaUpdateWrapper<Orders> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Orders::getId, orderCancelDTO.getId())
                .set(Orders::getStatus, OrdersConstant.ORDER_STATUS_REFUNDED)
                .set(Orders::getCancelReason, orderCancelDTO.getCancelReason());
        orderMapper.update(updateWrapper);
    }

    /**
     * 查询订单明细
     *
     * @param id
     */
    @Override
    public OrderVO getOrderById(String id) {
        // 查询订单
        Orders orders = orderMapper.selectById(id);

        // 查询订单明细
        LambdaQueryWrapper<OrderDetail> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderDetail::getOrderId, orders.getId());
        List<OrderDetail> orderDetails = orderDetailMapper.selectList(wrapper);

        // 组装数据
        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(orders, orderVO);
        // 分类前清空原有的列表
        orderVO.setOrderDetails(new ArrayList<>());
        orderVO.setOrderDetailOthers(new ArrayList<>());
        double totalAmount = 0.0;
        int totalCount = 0;
        // 遍历 orderDetails 列表并分类
        for (OrderDetail orderDetail : orderDetails) {
            if (Objects.equals(orderDetail.getType(), BusinessNameConstant.order_detail_product)) {
                totalCount++;
                totalAmount += orderDetail.getAmount() * orderDetail.getNumber();
            }

            if (Objects.equals(orderDetail.getType(), OrdersConstant.ORDER_DETAIL_TYPE_PRODUCT)) {
                // 如果 type 等于 0，添加到 orderDetails 列表
                orderVO.getOrderDetails().add(orderDetail);
            } else {
                // 否则，添加到 orderDetailOthers 列表
                orderVO.getOrderDetailOthers().add(orderDetail);
            }
        }
        orderVO.setTotalAmount(totalAmount);
        orderVO.setTotalNumber(totalCount);
        return orderVO;
    }

    /**
     * 再来一单
     *
     * @param id
     */
    @Override
    public void again(String id) {
        LambdaQueryWrapper<OrderDetail> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderDetail::getOrderId, id);
        List<OrderDetail> orderDetails = orderDetailMapper.selectList(wrapper);
        Orders orders = orderMapper.selectById(id);
        orderDetails.forEach(item -> {
            Products products = productsMapper.selectById(item.getProductId());
            if (products != null) {
                shoppingCartService.updateShoppingCart(ShoppingCartDTO.builder()
                        .amount(item.getAmount())
                        .number(item.getNumber())
                        .productId(item.getProductId())
                        .productSpecs(item.getProductSpecs())
                        .shopId(orders.getShopId())
                        .build());
            }
        });
    }
} 